package org.easy.tool.common;

import cn.hutool.core.date.ChineseDate;
import cn.hutool.core.date.DateUtil;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Valley
 * Created by Valley on 2023/7/14 15:39
 * 标准时间格式：YMD(ymd)表示yyyy-MM-dd MS(ms)表示yyyy-MM-dd HH:mm:ss
 * 中文时间格式: toCN表示(yyyy年MM月dd日 yyyy年MM月dd日HH时mm分ss秒)
 * 农历时间格式: toLunar表示农历(天干地支、正月等)
 * 时间戳时间格式: timestamp表示时间戳相关的
 * 计算相关格式：future表示未来时间, last表示过去时间
 * 日期字符串格式：日期类型使用date，字符串类型使用str
 * 格式化格式：pattern表示接收不同格式用于格式化
 */
public class TimeUtil {

    public static final long ONE_SECOND = 1000;

    public static final long ONE_MINUTE = ONE_SECOND * 60;

    public static final long ONE_HOUR = ONE_MINUTE * 60;

    public static final long ONE_DAY = ONE_HOUR * 24;

    public static final long ONE_WEEK = ONE_DAY * 7;

    public static final String YMD = "yyyy-MM-dd";

    public static final String YMDToCN = "yyyy年MM月dd日";

    public static final String MS = "yyyy-MM-dd HH:mm:ss";

    public static final String MSToCN = "yyyy年MM月dd日HH时mm分ss秒";


    /**
     * 功能：生成yyyyMMddHHmmss格式的当前时间字符串提供给文件使用
     */
    public static String nowMSFile() {
        return nowToPatternStr("yyyyMMddHHmmss");
    }

    /**
     * 功能：生成yyyy-MM-dd HH:mm:ss格式的字符串
     */
    public static String nowMS() {
        return nowToPatternStr(MS);
    }

    /**
     * 功能：生成当前时间的毫秒值
     */
    public static String nowMSToCN() {
        return nowToPatternStr(MSToCN);
    }

    /**
     * 功能：生成当前时间的毫秒值
     */
    public static long nowTimeStamp() {
        return new Date().getTime();
    }

    /**
     * 功能：生成yyyy-MM-dd格式的当前时间字符串
     */
    public static String today() {
        return nowToPatternStr(YMD);
    }

    /**
     * yyyy-MM-dd HH:mm:ss格式的今日0点字符串
     */
    public static String todayMS(){
        String today = todayYMD();
        return today + " 00:00:00";
    }

    /**
     * 功能：生成yyyy-MM-dd格式的昨天日期
     */
    public static String yesterdayYMD() {
        return yesterdayYMD(todayYMD());
    }

    /**
     * 功能：生成指定日期的昨天日期
     */
    public static String yesterdayYMD(String today) {
        return LocalDate.parse(today).minusDays(1).toString();
    }

    /**
     * 功能：获取过去指定天数的日期
     */
    public static List<String> lastDays(int dayLen) {
        return lastDays(today(), dayLen);
    }

    /**
     * 功能：获取过去指定天数的日期
     */
    public static List<String> lastDays(String date, int dayLen) {
        List<String> days = new ArrayList<>();
        for (int i = 0; i < dayLen; i++) {
            String yesterday = yesterdayYMD(date);
            days.add(yesterday);
            date = yesterday;
        }
        return days;
    }

    /**
     * 功能：生成yyyy-MM-dd格式的明天日期
     */
    public static String tomorrowYMD() {
        return tomorrowYMD(today());
    }

    /**
     * 功能：生成指定日期的明天日期
     */
    public static String tomorrowYMD(String today) {
        return LocalDate.parse(today).plusDays(1).toString();
    }

    /**
     * 仅支持日期格式yyyy-MM-dd
     */
    public static String ymdFutureYMD(String date, int num){
        return LocalDate.parse(date).plusDays(num).toString();
    }

    /**
     * 支持yyyy-MM-dd和yyyy-MM-dd HH:mm:ss格式
     */
    public static String futureDateTime(String dateTime, int num){
        String sub = StringUtil.sub(dateTime, 0, 10);
        return LocalDate.parse(sub).plusDays(num) + " 00:00:00";
    }

    /**
     * 功能：获取未来指定天数的日期
     */
    public static List<String> futureDays(int dayLen) {
        return futureDays(today(), dayLen);
    }

    /**
     * 功能：获取未来指定天数的日期
     */
    public static List<String> futureDays(String date, int dayLen) {
        List<String> days = new ArrayList<>();
        for (int i = 0; i < dayLen; i++) {
            String tomorrowDay = tomorrowYMD(date);
            days.add(tomorrowDay);
            date = tomorrowDay;
        }
        return days;
    }

    /**
     * 功能：生成yyyy年MM月dd日格式的当前时间字符串
     */
    public static String todayYMDToCN() {
        return dateToPatternStr(new Date(), YMDToCN);
    }

    /**
     * 生成yyyy-MM-dd格式的当前时间字符串
     */
    public static String todayYMD(){
        return dateToPatternStr(new Date(), YMD);
    }

    /**
     * 功能：生成指定格式的当前时间字符串
     */
    public static String nowToPatternStr(String pattern) {
        return dateToPatternStr(new Date(), pattern);
    }

    /**
     * 功能：生成指定时间指定格式的当前时间字符串
     */
    public static String dateToPatternStr(Date date, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }

    /**
     * 功能： 生成当前农历日期字符串
     */
    public static String todayYMDToLunar() {
        ChineseDate date = new ChineseDate(new Date());
        return date.toString();
    }

    /**
     * 功能： 生成指定农历日期字符串,默认yyyy-MM-dd格式
     */
    public static String ymdToLunar(String normalDate) {
        Date date = ymdToDate(normalDate);
        ChineseDate dateCN = new ChineseDate(date);
        return dateCN.toString();
    }

    /**
     * 功能：将指定格式字符串转化为时间，支持yyyy-MM-dd格式
     */
    public static Date ymdToDate(String date) {
        try {
            date = date.substring(0, 10);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            return format.parse(date);
        } catch (Exception e) {
            return new Date();
        }
    }

    public static String msToYMD(String msStr){
        msStr = msStr.substring(0, 10);
        Date date = ymdToDate(msStr);
        return dateToPatternStr(date, "yyyy-MM-dd");
    }


    /**
     * 参数时间与当前时间相差1天以上
     */
    public static boolean judgeOneDayInterval(String timeStr){
        long now = nowTimeStamp();
        long strMS = msToTimeStamp(timeStr);
        return now - strMS > ONE_DAY;
    }

    /**
     * 判断参数时间是否大于当前时间
     */
    public static boolean judgeFuture(String msStr) {
        long now = nowTimeStamp();
        long strMS = msToTimeStamp(msStr);
        return strMS > now;
    }

    public static boolean judgeFuture(String last, String future){
        long lastTime = msToTimeStamp(last);
        long futureTime = msToTimeStamp(future);
        return lastTime < futureTime;
    }

    /**
     * 判断参数时间是否小于当前时间
     */
    public static boolean judgeLast(String msStr) {
        return !judgeFuture(msStr);
    }

    /**
     * 字符串转化为时间戳
     * 将指定格式字符串转化为时间戳，支持2017-08-15 00:00:00格式
     */
    public static long msToTimeStamp(String lastTrainTime) {
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return format.parse(lastTrainTime).getTime();
        }catch (Exception e){
            return 0;
        }
    }

    /**
     * 将秒转化为文字格式
     */
    public static String secondToFormatText(int costTime) {
        int hours = costTime / 3600;
        int remainingSeconds = costTime % 3600;
        int minutes = remainingSeconds / 60;
        int seconds = remainingSeconds % 60;
        StringBuilder sb = new StringBuilder();
        if (hours > 0) {
            sb.append(hours).append("小时");
        }
        sb.append(minutes).append("分").append(seconds).append("秒");
        return sb.toString();
    }
}
